/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2017年4月22日
 * V4.0
 */
package com.jphenix.share.lang;

import com.jphenix.standard.docs.ClassInfo;

import java.util.Iterator;

/**
 * 循环存储迭代
 * 
 * com.jphenix.share.lang.RollIterator
 * 
 * 设置序列元素总数后，可以无限的存入。
 * 达到上限后，覆盖最早的数据
 * 
 * 由旧到新依次循环读取数据,在没有新增数据
 * 时读取全部数据后，结束读取数据
 * @author MBG
 * 2017年4月22日
 */
@ClassInfo({"2017-04-22 00:13","循环存储迭代"})
public class RollIterator<E> implements Iterator<E> {
	
	private int pointSet = -1; //存入元素指针  指针指向的是上一次放入的值
	private int pointGet = -1; //获取元素指针  指针指向的是上一次读取的值
	private Object[] elements = null; //核心数组

	/**
	 * 构造函数
	 * @param size 数组大小（上限）
	 * @author MBG
	 */
	public RollIterator(int size) {
		super();
		elements = new Object[size];
	}
	
	/**
	 * 是否存在下一个值
	 */
	@Override
	public boolean hasNext() {
        return pointSet != pointGet;
    }

	/**
	 * 放入值
	 * @param e 需要放入的值
	 * 2017年4月22日
	 * @author MBG
	 */
	public void add(E e) {
		if(pointSet>=elements.length-1) {
			//准备从头放入值
			if(pointGet==0) {
				//保存速度远远大于读取速度
				//需要放弃当前未读取的旧数据，将读取指针强制前移
				pointGet++;
				
			}
			pointSet = 0;
			elements[pointSet] = e;
			return;
		}
		if(pointSet==pointGet-1) {
			//保存速度远远大于读取速度
			//需要放弃当前未读取数据，将读取指针强制前移
			if(pointGet>=elements.length-1) {
				pointGet = 0;
			}else {
				pointGet++;
			}
		}
		elements[++pointSet] = e;
	}
	

	/**
	 * 获取下一个值
	 */
	@SuppressWarnings("unchecked")
	@Override
	public E next() {
		if(pointSet==pointGet) {
			return null;
		}
		if(pointGet>=elements.length-1) {
			//从头开始读
			pointGet = 0;
			return (E)elements[pointGet];
		}
		return (E)elements[++pointGet];
	}


	/**
	 * 移除下一个值
	 */
	@Override
	public void remove() {
		if(pointSet==pointGet) {
			return;
		}
		if(pointGet>=elements.length-1) {
			//从头开始读
			pointGet = 0;
			elements[pointGet] = null;
		}else {
			elements[++pointGet] = null;
		}
	}
	
	/**
	 * 缓存大小
	 * @return 缓存大小
	 * 2017年4月22日
	 * @author MBG
	 */
	public int size() {
		return elements.length;
	}
	
	/**
	 * 清空全部内容
	 * 2017年4月22日
	 * @author MBG
	 */
	public void clear() {
		reset();
	}
	
	/**
	 * 重置内容
	 * 2017年4月22日
	 * @author MBG
	 */
	public void reset() {
		for(int i=0;i<elements.length;i++) {
			elements[i] = null;
		}
		pointGet = -1;
		pointSet = -1;
	}
	
	/**
	 * 重置内容
	 * @param size 重新分配大小
	 * 2017年4月22日
	 * @author MBG
	 */
	public void reset(int size) {
		for(int i=0;i<elements.length;i++) {
			elements[i] = null;
		}
		elements = new Object[size];
		pointGet = -1;
		pointSet = -1;
	}
}
